using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
using System.Configuration;

namespace CE.Security
{
    public class MySecurity
    {
        /// <summary>
        /// Encrypt a string using dual encryption method. Return a encrypted cipher Text
        /// </summary>
        /// <param name="toEncrypt">string to be encrypted</param>
        /// <param name="useHashing">use hashing? send to for extra secirity</param>
        /// <returns></returns>
        public static string Encrypt(string toEncrypt, bool useHashing)
        {
            byte[] keyArray;
            byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);

            System.Configuration.AppSettingsReader settingsReader = new AppSettingsReader();
            // Get the key from config file
            //string key = (string)settingsReader.GetValue("SecurityKey", typeof(String));
            string key = CE.Configuration.MyConfigurationManager.GetAppSettingValue("CXCRMSecurityKey");
            //System.Windows.Forms.MessageBox.Show(key);
            if (useHashing)
            {
                MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
                keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
                hashmd5.Clear();
            }
            else
                keyArray = UTF8Encoding.UTF8.GetBytes(key);

            TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
            tdes.Key = keyArray;
            tdes.Mode = CipherMode.ECB;
            tdes.Padding = PaddingMode.PKCS7;

            ICryptoTransform cTransform = tdes.CreateEncryptor();
            byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
            tdes.Clear();
            return Convert.ToBase64String(resultArray, 0, resultArray.Length);
        }
        /// <summary>
        /// DeCrypt a string using dual encryption method. Return a DeCrypted clear string
        /// </summary>
        /// <param name="cipherString">encrypted string</param>
        /// <param name="useHashing">Did you use hashing to encrypt this data? pass true is yes</param>
        /// <returns></returns>
        public static string Decrypt(string cipherString, bool useHashing)
        {
            byte[] keyArray;
            byte[] toEncryptArray = Convert.FromBase64String(cipherString);

            System.Configuration.AppSettingsReader settingsReader = new AppSettingsReader();
            //Get your key from config file to open the lock!
            //string key = (string)settingsReader.GetValue("SecurityKey", typeof(String));
            string key = CE.Configuration.MyConfigurationManager.GetAppSettingValue("CXCRMSecurityKey");

            if (useHashing)
            {
                MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
                keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
                hashmd5.Clear();
            }
            else
                keyArray = UTF8Encoding.UTF8.GetBytes(key);

            TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
            tdes.Key = keyArray;
            tdes.Mode = CipherMode.ECB;
            tdes.Padding = PaddingMode.PKCS7;

            ICryptoTransform cTransform = tdes.CreateDecryptor();
            byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);

            tdes.Clear();
            return UTF8Encoding.UTF8.GetString(resultArray);
        }

        protected bool CheckMasterVisa(string strCardNumber)
        {
            bool _retValue = false;
            string StrNum = "";
            Int32[] NumArray = new Int32[15];
            int x = 0;
            int c0, c2, c4, c6, c8, c10, c12, c14;

            //Dim A1

            StrNum = strCardNumber;

            //'MsgBox Len(StrNum)
            for(x =1; x <= StrNum.Length;x++)
            {
                NumArray[x - 1] = Convert.ToInt32(StrNum.Substring(x, 1));
                //'MsgBox NumArray(X - 1)
            }

            c0 = NumArray[0] * 2;
            c2 = NumArray[2] * 2;
            c4 = NumArray[4] * 2;
            c6 = NumArray[6] * 2;
            c8 = NumArray[8] * 2;
            c10 = NumArray[10] * 2;
            c12 = NumArray[12] * 2;
            c14 = NumArray[14] * 2;

            if (c0 >= 10)
                NumArray[0] = Convert.ToInt32(c0.ToString().Substring(0, 1)) + Convert.ToInt32(c0.ToString().Substring(1, 1));
            else
                NumArray[0] = c0;

            if (c2 >= 10)
                NumArray[2] = Convert.ToInt32(c2.ToString().Substring(0, 1)) + Convert.ToInt32(c2.ToString().Substring(1, 1));
            else
                NumArray[2] = c2;

            if (c4 >= 10)
                NumArray[4] = Convert.ToInt32(c4.ToString().Substring(0, 1)) + Convert.ToInt32(c4.ToString().Substring(1, 1));
            else
                NumArray[4] = c4;

            if (c6 >= 10)
                NumArray[6] = Convert.ToInt32(c6.ToString().Substring(0, 1)) + Convert.ToInt32(c6.ToString().Substring(1, 1));
            else
                NumArray[6] = c6;

            if (c8 >= 10)
                NumArray[8] = Convert.ToInt32(c8.ToString().Substring(0, 1)) + Convert.ToInt32(c8.ToString().Substring(1, 1));
            else
                NumArray[8] = c8;

            if (c10 >= 10)
                NumArray[10] = Convert.ToInt32(c10.ToString().Substring(0, 1)) + Convert.ToInt32(c10.ToString().Substring(1, 1));
            else
                NumArray[10] = c10;

            if (c12 >= 10)
                NumArray[12] = Convert.ToInt32(c12.ToString().Substring(0, 1)) + Convert.ToInt32(c12.ToString().Substring(1, 1));
            else
                NumArray[12] = c12;

            if (c14 >= 10)
                NumArray[14] = Convert.ToInt32(c14.ToString().Substring(0, 1)) + Convert.ToInt32(c14.ToString().Substring(1, 1));
            else
                NumArray[14] = c0;

            int value;

            value = 0;
            for(x = 0;x<15;x++)
                value = value + NumArray[x];
            

            if (Convert.ToInt32((value.ToString().Substring(1, 1))) != 0)
                _retValue = false;
            else
                _retValue = true;


            return _retValue;
        }


        /// <summary>
        /// Phyo - 23/Jun/2010
        /// Validates a credit card number using the standard Luhn/mod10
        /// validation algorithm.
        /// Reference : http://en.wikipedia.org/wiki/Luhn_algorithm
        /// Source Code : http://www.codeguru.com/csharp/.net/net_security/authentication/article.php/c12283/
        /// </summary>
        /// <param name="cardNumber">Card number, with or without
        ///        punctuation</param>
        /// <returns>True if card number appears valid, false if not
        /// </returns>
        public bool IsCreditCardValid(string cardNumber)
        {
            const string allowed = "0123456789";
            int i;

            StringBuilder cleanNumber = new StringBuilder();
            for (i = 0; i < cardNumber.Length; i++)
            {
                if (allowed.IndexOf(cardNumber.Substring(i, 1)) >= 0)
                    cleanNumber.Append(cardNumber.Substring(i, 1));
            }
            if (cleanNumber.Length < 13 || cleanNumber.Length > 16)
                return false;

            for (i = cleanNumber.Length + 1; i <= 16; i++)
                cleanNumber.Insert(0, "0");

            int multiplier, digit, sum, total = 0;
            string number = cleanNumber.ToString();

            for (i = 1; i <= 16; i++)
            {
                multiplier = 1 + (i % 2);
                digit = int.Parse(number.Substring(i - 1, 1));
                sum = digit * multiplier;
                if (sum > 9)
                    sum -= 9;
                total += sum;
            }
            return (total % 10 == 0);
        }
    }
}
